package com.hotel.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotel.entity.Member;
import com.hotel.dto.MemberDTO;
import com.hotel.vo.MemberVO;
import com.hotel.mapper.MemberMapper;
import com.hotel.service.MemberService;
import com.hotel.service.PointsRecordService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 会员服务实现类
 */
@Service
public class MemberServiceImpl extends ServiceImpl<MemberMapper, Member> implements MemberService {
    
    @Autowired
    private MemberMapper memberMapper;
    
    @Autowired
    private PointsRecordService pointsRecordService;
    
    @Override
    public Page<MemberVO> getMemberPage(int current, int size, String keyword, String level, Integer status) {
        Page<Member> page = new Page<>(current, size);
        
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        
        // 关键词搜索
        if (StringUtils.hasText(keyword)) {
            wrapper.and(w -> w.like(Member::getName, keyword)
                    .or().like(Member::getPhone, keyword)
                    .or().like(Member::getMemberNo, keyword));
        }
        
        // 等级过滤
        if (StringUtils.hasText(level)) {
            wrapper.eq(Member::getLevel, level);
        }
        
        // 状态过滤
        if (status != null) {
            wrapper.eq(Member::getStatus, status);
        }
        
        wrapper.orderByDesc(Member::getCreateTime);
        
        Page<Member> memberPage = this.page(page, wrapper);
        
        // 转换为VO
        Page<MemberVO> voPage = new Page<>();
        BeanUtils.copyProperties(memberPage, voPage);
        
        List<MemberVO> voList = memberPage.getRecords().stream().map(member -> {
            MemberVO vo = new MemberVO();
            BeanUtils.copyProperties(member, vo);
            return vo;
        }).collect(Collectors.toList());
        
        voPage.setRecords(voList);
        return voPage;
    }
    
    @Override
    public MemberVO getMemberById(Long id) {
        Member member = this.getById(id);
        if (member == null) {
            return null;
        }
        
        MemberVO vo = new MemberVO();
        BeanUtils.copyProperties(member, vo);
        return vo;
    }
    
    @Override
    @Transactional
    public boolean createMember(MemberDTO memberDTO) {
        Member member = new Member();
        BeanUtils.copyProperties(memberDTO, member);
        
        // 生成会员号
        member.setMemberNo(generateMemberNo());
        member.setLevel("bronze"); // 默认铜牌会员
        member.setPoints(0);
        member.setTotalConsumption(0.0);
        member.setStatus(1);
        member.setCreateTime(LocalDateTime.now());
        member.setUpdateTime(LocalDateTime.now());
        
        return this.save(member);
    }
    
    @Override
    @Transactional
    public boolean updateMember(Long id, MemberDTO memberDTO) {
        Member member = this.getById(id);
        if (member == null) {
            return false;
        }
        
        BeanUtils.copyProperties(memberDTO, member, "id", "memberNo", "createTime");
        member.setUpdateTime(LocalDateTime.now());
        
        return this.updateById(member);
    }
    
    @Override
    @Transactional
    public boolean deleteMember(Long id) {
        return this.removeById(id);
    }
    
    @Override
    public Member getMemberByPhone(String phone) {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getPhone, phone);
        return this.getOne(wrapper);
    }
    
    @Override
    public Member getMemberByMemberNo(String memberNo) {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Member::getMemberNo, memberNo);
        return this.getOne(wrapper);
    }
    
    @Override
    @Transactional
    public boolean updateMemberPoints(Long memberId, Integer points, String source, String description) {
        Member member = this.getById(memberId);
        if (member == null) {
            return false;
        }
        
        // 更新积分
        member.setPoints(member.getPoints() + points);
        member.setUpdateTime(LocalDateTime.now());
        
        boolean result = this.updateById(member);
        
        // 记录积分变动
        if (result) {
            pointsRecordService.addPointsRecord(memberId, points > 0 ? "earn" : "redeem", 
                    Math.abs(points), source, null, description);
        }
        
        return result;
    }
    
    @Override
    @Transactional
    public boolean upgradeMemberLevel(Long memberId, String newLevel) {
        Member member = this.getById(memberId);
        if (member == null) {
            return false;
        }
        
        member.setLevel(newLevel);
        member.setUpdateTime(LocalDateTime.now());
        
        return this.updateById(member);
    }
    
    @Override
    @Transactional
    public boolean updateMemberStatus(Long memberId, Integer status) {
        Member member = this.getById(memberId);
        if (member == null) {
            return false;
        }
        
        member.setStatus(status);
        member.setUpdateTime(LocalDateTime.now());
        
        return this.updateById(member);
    }
    
    @Override
    public Map<String, Object> getMemberStats() {
        Map<String, Object> stats = new HashMap<>();
        
        // 总会员数
        long total = this.count();
        stats.put("total", total);
        
        // 活跃会员数（状态为1）
        LambdaQueryWrapper<Member> activeWrapper = new LambdaQueryWrapper<>();
        activeWrapper.eq(Member::getStatus, 1);
        long active = this.count(activeWrapper);
        stats.put("active", active);
        
        // 总消费额
        Double totalConsumption = memberMapper.getTotalConsumption();
        stats.put("totalConsumption", totalConsumption != null ? totalConsumption : 0.0);
        
        // 总积分
        Integer totalPoints = memberMapper.getTotalPoints();
        stats.put("totalPoints", totalPoints != null ? totalPoints : 0);
        
        // 计算增长率（模拟数据）
        stats.put("totalChange", 12.5);
        stats.put("activeChange", 8.3);
        stats.put("consumptionChange", 15.2);
        stats.put("pointsChange", 6.8);
        
        return stats;
    }
    
    @Override
    public List<Map<String, Object>> getMemberLevelDistribution() {
        return memberMapper.getMemberLevelDistribution();
    }
    
    @Override
    public List<Map<String, Object>> getMemberGrowthTrend(String type) {
        return memberMapper.getMemberGrowthTrend(type);
    }
    
    @Override
    @Transactional
    public boolean batchOperation(List<Long> memberIds, String operation, Object params) {
        if (memberIds == null || memberIds.isEmpty()) {
            return false;
        }
        
        switch (operation) {
            case "freeze":
                return batchUpdateStatus(memberIds, 0);
            case "unfreeze":
                return batchUpdateStatus(memberIds, 1);
            case "upgrade":
                return batchUpgradeLevel(memberIds, (String) params);
            case "points":
                return batchUpdatePoints(memberIds, (Integer) params);
            default:
                return false;
        }
    }
    
    @Override
    public void exportMemberData(String level, Integer status) {
        // TODO: 实现数据导出功能
        // 可以使用 EasyExcel 或 Apache POI 实现
    }
    
    /**
     * 生成会员号
     */
    private String generateMemberNo() {
        String prefix = "M";
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        
        // 查询当天最大序号
        String pattern = prefix + timestamp + "%";
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(Member::getMemberNo, pattern)
                .orderByDesc(Member::getMemberNo)
                .last("LIMIT 1");
        
        Member lastMember = this.getOne(wrapper);
        
        int sequence = 1;
        if (lastMember != null) {
            String lastMemberNo = lastMember.getMemberNo();
            String lastSequence = lastMemberNo.substring(lastMemberNo.length() - 4);
            sequence = Integer.parseInt(lastSequence) + 1;
        }
        
        return prefix + timestamp + String.format("%04d", sequence);
    }
    
    /**
     * 批量更新状态
     */
    private boolean batchUpdateStatus(List<Long> memberIds, Integer status) {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Member::getId, memberIds);
        
        Member updateMember = new Member();
        updateMember.setStatus(status);
        updateMember.setUpdateTime(LocalDateTime.now());
        
        return this.update(updateMember, wrapper);
    }
    
    /**
     * 批量升级等级
     */
    private boolean batchUpgradeLevel(List<Long> memberIds, String level) {
        LambdaQueryWrapper<Member> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(Member::getId, memberIds);
        
        Member updateMember = new Member();
        updateMember.setLevel(level);
        updateMember.setUpdateTime(LocalDateTime.now());
        
        return this.update(updateMember, wrapper);
    }
    
    /**
     * 批量更新积分
     */
    private boolean batchUpdatePoints(List<Long> memberIds, Integer points) {
        for (Long memberId : memberIds) {
            updateMemberPoints(memberId, points, "batch_operation", "批量积分调整");
        }
        return true;
    }
}